/***************************************************************************
 *   Copyleft 2008-2009 by												   *
 *	 Iwanicki Krzysztof													   *
 *   <gamma.mini.pw.edu.pl/~iwanickik>									   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 ***************************************************************************/
#ifndef __VPAINTER_H__
#define __VPAINTER_H__

// Includes
//#include "../Fonts/Font.h"
#include <Math/vMath.h>
#include "../../Utils/vUtils.h"
#include "../Graphics/vColor.h"
#include "../Macros/vMemoryMacros.h"

namespace Vendetta {
	/**
	 *	Abstract 2D and 3D painter class.
	 *	It's is a class that provides basic geometry Drawing interface.
	 *	is required (e.g. to set 2D orthographic projection or to change colors).
	 *	@see cState
	 *	@see cView
	 */
	class  vPainter {
	public:

		/**
		 *	Default constructor.
		 */
		vPainter();

		/**
		 *	Default destructor.
		 */
		virtual ~vPainter();

		/**
		 *	Draws text.
		 *	@param font font to be used
		 *	@param text text to be rendered
		 */
		//virtual vVoid DrawText(const cFontHandler& fontHandler, const cString& text) = 0;

		/**
		 *	Draws wrapped (if wanted) text in given rectangle.
		 *	Optimized for displaying only what's visible.
		 *	@param font font to be used
		 *	@param lines queue of lines of text (head of this queue points to last line)
		 *	@param lastLine last line to be displayed (the one at the bottom of rectangle)
		 *	@param rectangle rectangle in which text should be displayed
		 *	@param wrap shall the lines be wrapped? (yes - by default)
		 *	@param downToUp shall rendering start at the bottom and finish at the top or upside down?
		 */
		//virtual vVoid DrawText(const cFontHandler& fontHandler, const cQueue<cString> &lines, const vInt lastLine, const vRectangle& rectangle, const cBool wrap = true, const cBool downToUp = true) = 0;

		/**
		 *	Draws point.
		 *	@param coords XY coordinates of a point
		 */
		virtual vVoid DrawPoint(const vVector2D& coords) const = 0;

		/**
		 *	Draws point.
		 *	@param coords XYZ coordinates of a point
		 */
		virtual vVoid DrawPoint(const vVector3D& coords) const = 0;

		/**
		 *	Draws line.
		 *	@param coordsA XY coordinates of a first line's point
		 *	@param coordsB XY coordinates of a second line's point
		 */
		virtual vVoid DrawLine(const vVector2D& coordsA, const vVector2D& coordsB) const = 0;

		/**
		 *	Draws line.
		 *	@param coordsA XYZ coordinates of a first line's point
		 *	@param coordsB XYZ coordinates of a second line's point
		 */
		virtual vVoid DrawLine(const vVector3D& coordsA, const vVector3D& coordsB) const = 0;

		/**
		 *	Draws rectangle.
		 *	@param rectangle rectangle's coords
		 */
		virtual vVoid DrawRectangle(const vRectangle& rectangle) const = 0;

		/**
		 *	Draws textured rectangle.
		 *	@param rectangle rectangle's coords
		 *	@param texCoords rectangle's texture coordinates
		 */
		virtual vVoid DrawRectangle(const vRectangle& rectangle, const vRectangle& texCoords) const = 0;

		/**
		 *	Draws rectangle.
		 *	@param leftTop XY coordinates of a top left rectangle's corner
		 *	@param rightBottom XY coordinates of a top left rectangle's corner
		 */
		virtual vVoid DrawRectangle(const vVector2D& min, const vVector2D& max) const = 0;

		/**
		 *	Draws textured rectangle.
		 *	@param leftTop XY coordinates of a top left rectangle's corner
		 *	@param rightBottom XY coordinates of a top left rectangle's corner
		 */
		virtual vVoid DrawRectangle(const vVector2D& min, const vVector2D& max, const vVector2D& minTexCoords, const vVector2D& maxTexCoords) const = 0;

		/**
		 *	Draws rectangle strip.
		 *	@param rectangle rectangle's coords
		 */
		virtual vVoid DrawRectangleStrip(const vRectangle& rectangle) const = 0;

		/**
		 *	Draws textured triangle (unless filling mode is not set to WIRE).
		 *	@param coordsA XY coordinates of a first triangle's vertex
		 *	@param coordsB XY coordinates of a second triangle's vertex
		 *	@param coordsC XY coordinates of a third triangle's vertex
		 */
		virtual vVoid DrawTriangle(const vVector2D& coordsA, const vVector2D& coordsB, const vVector2D& coordsC) const = 0;

		/**
		 *	Draws textured triangle (unless filling mode is not set to WIRE).
		 *	@param coordsA XYZ coordinates of a first triangle's vertex
		 *	@param coordsB XYZ coordinates of a second triangle's vertex
		 *	@param coordsC XYZ coordinates of a third triangle's vertex
		 */
		virtual vVoid DrawTriangle(const vVector3D& coordsA, const vVector3D& coordsB, const vVector3D& coordsC) const = 0;

		/**
		 *	Draws textured and textured (unless filling mode is not set to WIRE) triangle.
		 *	@param coordsA XY coordinates of a first triangle's vertex
		 *	@param coordsB XY coordinates of a first triangle's vertex
		 *	@param coordsC XY coordinates of a first triangle's vertex
		 *	@param texCoordsA UV texture coordinates of a first triangle's vertex
		 *	@param texCoordsB UV texture coordinates of a second triangle's vertex
		 *	@param texCoordsC UV texture coordinates of a third triangle's vertex
		 */
		virtual vVoid DrawTriangle(const vVector2D& coordsA, const vVector2D& coordsB, const vVector2D& coordsC, const vVector2D& texCoordsA, const vVector2D& texCoordsB, const vVector2D& texCoordsC) const = 0;

		/**
		 *	Draws textured and textured (unless filling mode is not set to WIRE) triangle.
		 *	@param coordsA XYZ coordinates of a first triangle's vertex
		 *	@param coordsB XYZ coordinates of a first triangle's vertex
		 *	@param coordsC XYZ coordinates of a first triangle's vertex
		 *	@param texCoordsA UV texture coordinates of a first triangle's vertex
		 *	@param texCoordsB UV texture coordinates of a second triangle's vertex
		 *	@param texCoordsC UV texture coordinates of a third triangle's vertex
		 */
		virtual vVoid DrawTriangle(const vVector3D& coordsA, const vVector3D& coordsB, const vVector3D& coordsC, const vVector2D& texCoordsA, const vVector2D& texCoordsB, const vVector2D& texCoordsC) const = 0;

		/**
		 *	Draws triangle's outlining.
		 *	@param coordsA XY coordinates of a first triangle's vertex
		 *	@param coordsB XY coordinates of a second triangle's vertex
		 *	@param coordsC XY coordinates of a third triangle's vertex
		 */
		virtual vVoid DrawTriangleStrip(const vVector2D& coordsA, const vVector2D& coordsB, const vVector2D& coordsC) const = 0;

		/**
		 *	Draws triangle's outlining.
		 *	@param coordsA XYZ coordinates of a first triangle's vertex
		 *	@param coordsB XYZ coordinates of a second triangle's vertex
		 *	@param coordsC XYZ coordinates of a third triangle's vertex
		 */
		virtual vVoid DrawTriangleStrip(const vVector3D& coordsA, const vVector3D& coordsB, const vVector3D& coordsC) const = 0;

		/**
		 *	Draws textured quad (unless filling mode is not set to WIRE).
		 *	@param coordsA XY coordinates of a first quad's vertex
		 *	@param coordsB XY coordinates of a second quad's vertex
		 *	@param coordsC XY coordinates of a third quad's vertex
		 *	@param coordsD XY coordinates of a fourth quad's vertex
		 */
		virtual vVoid DrawQuad(const vVector2D& coordsA, const vVector2D& coordsB, const vVector2D& coordsC, const vVector2D& coordsD) const = 0;

		/**
		 *	Draws textured quad (unless filling mode is not set to WIRE).
		 *	@param coordsA XYZ coordinates of a first quad's vertex
		 *	@param coordsB XYZ coordinates of a second quad's vertex
		 *	@param coordsC XYZ coordinates of a third quad's vertex
		 *	@param coordsD XYZ coordinates of a fourth quad's vertex
		 */
		virtual vVoid DrawQuad(const vVector3D& coordsA, const vVector3D& coordsB, const vVector3D& coordsC, const vVector3D& coordsD) const = 0;

		/**
		 *	Draws textured and textured (unless filling mode is not set to WIRE) quad.
		 *	@param coordsA XY coordinates of a first quad's vertex
		 *	@param coordsB XY coordinates of a first quad's vertex
		 *	@param coordsC XY coordinates of a first quad's vertex
		 *	@param coordsD XY coordinates of a first quad's vertex
		 *	@param texCoordsA UV texture coordinates of a first quad's vertex
		 *	@param texCoordsB UV texture coordinates of a second quad's vertex
		 *	@param texCoordsC UV texture coordinates of a third quad's vertex
		 *	@param texCoordsD UV texture coordinates of a third quad's vertex
		 */
		virtual vVoid DrawQuad(const vVector2D& coordsA, const vVector2D& coordsB, const vVector2D& coordsC, const vVector2D& coordsD, const vVector2D& texCoordsA, const vVector2D& texCoordsB, const vVector2D& texCoordsC, const vVector2D& texCoordsD) const = 0;

		/**
		 *	Draws textured and textured (unless filling mode is not set to WIRE) quad.
		 *	@param coordsA XYZ coordinates of a first quad's vertex
		 *	@param coordsB XYZ coordinates of a first quad's vertex
		 *	@param coordsC XYZ coordinates of a first quad's vertex
		 *	@param coordsD XYZ coordinates of a first quad's vertex
		 *	@param texCoordsA UV texture coordinates of a first quad's vertex
		 *	@param texCoordsB UV texture coordinates of a second quad's vertex
		 *	@param texCoordsC UV texture coordinates of a third quad's vertex
		 *	@param texCoordsD UV texture coordinates of a third quad's vertex
		 */
		virtual vVoid DrawQuad(const vVector3D& coordsA, const vVector3D& coordsB, const vVector3D& coordsC, const vVector3D& coordsD, const vVector2D& texCoordsA, const vVector2D& texCoordsB, const vVector2D& texCoordsC, const vVector2D& texCoordsD) const = 0;

		/**
		 *	Draws quad's outlining.
		 *	@param coordsA XY coordinates of a first quad's vertex
		 *	@param coordsB XY coordinates of a second quad's vertex
		 *	@param coordsC XY coordinates of a third quad's vertex
		 *	@param coordsD XY coordinates of a fourth quad's vertex
		 */
		virtual vVoid DrawQuadStrip(const vVector2D& coordsA, const vVector2D& coordsB, const vVector2D& coordsC, const vVector2D& coordsD) const = 0;

		/**
		 *	Draws quad's outlining.
		 *	@param coordsA XYZ coordinates of a first quad's vertex
		 *	@param coordsB XYZ coordinates of a second quad's vertex
		 *	@param coordsC XYZ coordinates of a third quad's vertex
		 *	@param coordsD XYZ coordinates of a fourth quad's vertex
		 */
		virtual vVoid DrawQuadStrip(const vVector3D& coordsA, const vVector3D& coordsB, const vVector3D& coordsC, const vVector3D& coordsD) const = 0;

		/**
		 *	Draws polygon.
		 *	@param coords array of XY coordinates of conscutive poly's verts;
		 */
		virtual vVoid DrawPolygon(const vArray<vVector2D>& coords) const = 0;

		/**
		 *	Draws polygon.
		 *	@param coords array of XYZ coordinates of consecutive poly's verts;
		 */
		virtual vVoid DrawPolygon(const vArray<vVector3D>& coords) const = 0;

		/**
		 *	Draws textured polygon.
		 *	@param coords array of XY coordinates of consecutive poly's verts;
		 *	@param texCoords array of UV texture coordinates of consecutive poly's verts;
		 */
		virtual vVoid DrawPolygon(const vArray<vVector2D>& coords, const vArray<vVector2D>& texCoords) const = 0;

		/**
		 *	Draws textured polygon.
		 *	@param coords array of XY coordinates of consecutive poly's verts;
		 *	@param texCoords array of UV texture coordinates of consecutive poly's verts;
		 *	@param colors array of colors of consecutive poly's verts;
		 */
		virtual vVoid DrawPolygon(const vArray<vVector2D>& coords, const vArray<vVector2D>& texCoords, const vArray<vColor>& colors) const = 0;

		/**
		 *	Draws textured polygon.
		 *	@param coords array of XY coordinates of consecutive poly's verts;
		 *	@param colors array of colors of consecutive poly's verts;
		 */
		virtual vVoid DrawPolygonWithColors(const vArray<vVector2D>& coords, const vArray<vColor>& colors) const = 0;

		/**
		 *	Draws textured polygon.
		 *	@param coords array of XYZ coordinates of consecutive poly's verts;
		 *	@param texCoords array of UV texture coordinates of consecutive poly's verts;
		 */
		virtual vVoid DrawPolygon(const vArray<vVector3D>& coords, const vArray<vVector2D>& texCoords) const = 0;

	};
}

#endif //__VPAINTER_H__